#include <bits/stdc++.h>
#pragma GCC optimize(2)
using namespace std;

const int B = 800;
const int N = 200020;

struct Query {int u, x, id;} q[N];

int n, Q, c, a[N], sum[(1 << 15) + 10], vis[N], sz[N];
int zx, f[N], fa[N], b[N], cnt, tot, usd[N], ans[N];
vector<int> g[N];
vector<Query> qry[N];

void find(int u, int fa, int siz) {
    sz[u] = 1; int mx = 0;
    for (auto v : g[u]) {
        if (v == fa || vis[v]) continue;
        find(v, u, siz); sz[u] += sz[v];
        mx = max(mx, sz[v]);
    }
    if (mx <= siz / 2 && siz - sz[u] <= siz / 2)
        zx = u;
}

void dfs(int u, int fa, int siz) {
    f[u] = f[fa] | (1 << a[u]);
    b[++cnt] = f[u]; 
    if (siz > B) sum[f[u]]++;
    sz[u] = 1;
    // cout << "u = " << u << " f = " << f[u] << endl;
    for (auto j : qry[u])
        if (usd[j.id] == 0) q[++tot] = j;
    for (auto v : g[u]) {
        if (vis[v] || v == fa) continue;
        dfs(v, u, siz); sz[u] += sz[v];
    }
}

void solve(int u, int siz) {
    find(u, 0, siz);
    dfs(zx, 0, siz);
    if (siz > B) {
        for (int i = 0; i <= c - 1; i++)
            for (int j = 0; j < (1 << c); j++)
                if ((j & (1 << i)) == 0)
                    sum[j + (1 << i)] += sum[j];
    }
    for (int i = 1; i <= tot; i++) {
        if ((f[q[i].u] | q[i].x) == q[i].x) {
            usd[q[i].id] = 1;
            if (siz > B) {
                ans[q[i].id] = sum[q[i].x];
            } else {
                for (int j = 1; j <= cnt; j++)
                    if ((b[j] | q[i].x) == q[i].x)
                        ans[q[i].id]++; 
            }
            // if (ans[q[i].id] == 1094) {
            //     int res = 0;
            //     cout << "id = " << q[i].id << " x = " << q[i].x << " siz = " << siz << endl;
            //     for (int j = 1; j <= cnt; j++)
            //         if ((b[j] | q[i].x) == q[i].x)
            //             res++; 
            //     cout << "res = " << res << " " << cnt << " " << b[2] << endl;
            // }
            // if (q[i].x == (1 << c) - 1)
            //     cout << "ans = " << ans[q[i].id] << " " << siz << " " << sum[(1 << c) - 1] << endl;
        }
    }
    if (siz > B) memset(sum, 0, sizeof(sum));
    cnt = tot = 0; vis[zx] = 1;
    for (auto v : g[zx]) {
        if (vis[v]) continue;
        solve(v, sz[v]);
    }
}

int main() {
    freopen("tree.in", "r", stdin);
    freopen("tree.out", "w", stdout);
    // int st = clock();
    scanf("%d%d%d", &n, &Q, &c);
    for (int i = 1; i <= n; i++)
        scanf("%d", &a[i]);
    for (int i = 2; i <= n; i++) {
        scanf("%d", &fa[i]);
        g[fa[i]].push_back(i);
        g[i].push_back(fa[i]);
    }
    for (int i = 1; i <= Q; i++) {
        Query x; scanf("%d%d", &x.x, &x.u);
        x.id = i; qry[x.u].push_back(x);
    }
    solve(1, n);
    for (int i = 1; i <= Q; i++) {
        if (usd[i] == 0) printf("1\n");
        else printf("%d\n", ans[i]);
    }
    // cout << "time = " << clock() - st << endl;
    return 0;
}